1. Field of the Invention
The present invention is directed to technology for adding functionality to existing code in order to access information.
2. Description of the Related Art
As the Internet's popularity grows, more businesses are establishing a presence on the Internet. These businesses typically set up web sites that run one or more web applications. One disadvantage of doing business on the Internet is that if the web site goes down, becomes unresponsive or otherwise is not properly serving customers, the business is losing potential sales and/or customers. Analogous issues exist with Intranets and Extranets. Thus, there is a need to monitor live web applications (including Intranets, Extranets, applications on the World Wide Web, and others) to make sure that they are running properly.
If an application crashes or is not working as expected, an inquiry may be made as to why that application crashes or is not working as expected. Examples of information that may be useful in such an inquiry include return values and exceptions. A return value is data provided from a given method upon exit from that method. For example, in the JAVA programming language the “return” statement is used to exit from the current method and proceed with the statement that follows the original method call. There are two forms of return: one returns a value and one doesn't. To return a value, the value or an expression that calculates the value is placed after the “return” keyword. (JAVA is a trademark of SUN Microsystems, Incorporated.)
An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. Many kinds of errors can cause exceptions. They range from serious hardware errors, such as a hard disk crash, to simple programming errors, such as trying to access an out-of-bounds array element. When such an error occurs within a JAVA method, the method creates an exception object and hands it off to the run time system. The exception object contains the information about the error, including its type and, possibly, the state of the program when the error occurred. The run time system is then responsible for finding some code to handle the error. In JAVA terminology, creating an exception object and handing it to the run time system is called throwing an exception.
After a method throws an exception, the run time system attempts to find something to handle the exception. The set of possible “somethings” to handle the exception includes the, set of methods in the call stack of the method where the error occurred. The run time system searches backwards through the call stack, beginning with the method in which the error occurred, until it finds a method that contains an appropriate exception handler. An exception handler is considered appropriate if the type of exception thrown is the same type as (or a subclass of) the type of exception handled by the handler. The exception bubbles up through the call stack until an appropriate handler is found and one of the calling methods handles the exception. The exception handler chosen is said to catch the exception. If the run time system exhaustively searches all the methods in the call stack without finding an appropriate exception handler, the thread terminates. A method can catch an exception by providing an exception handler for that type of exception.
The first step in constructing an exception handler is to enclose the statements that might throw an exception within a “Try” block. Exception handlers are associated with a “Try” block by providing one or more “Catch” blocks directly after the “Try” block. Each “Catch” block is an exception handler and handles the type of exception indicated by its argument. Exception handling may optionally include a means for cleaning up before allowing control to be passed to a different part of the program. This can be done by enclosing the clean up code within a “Finally” block. The “Finally” block in the JAVA code provides a mechanism that allows a method to clean up after itself regardless of what happens within the “Try” block. Consider the following pseudocode as an example:
public foo( )  {  try {     [JAVA instructions]  } catch (ExceptionType name) {     [code for “Catch” block]  } finally {     [code for “Finally” block]  }}
The method foo( ) is comprised of logic implemented by [JAVA instructions]. These [JAVA instructions] are enclosed in a “Try ” block. If an exception of type ExceptionType occurs while performing the [JAVA instructions], then the “Catch ” block is performed. Regardless of whether the method runs without error or there is an exception, the “Finally ” block will be performed. The “Finally ” block is performed after the “try ” block and the “Catch ” handler.
Accessing the exception or return value can be valuable for debugging. Thus, some programmers will add Try, Catch and Finally statements when creating their code to deal with and/or learn about the exceptions. Additionally, programmers can add code to report return values.
The process of adding code to report return values and exceptions can also be automated. For example, some performance analysis tools may perform their intended function by automatically modifying source code to add new functionality that enables the original software to be monitored. Modifying source code involves adding new instructions to source code and/or modifying existing instructions in the source code. A significant problem with modifying source code is that the source code may not be available. Another problem with modifying source code is that the code will need to be re-compiled for the modification and re-compiled again to remove the modification.
Thus, there is a need for an improved mechanism to provide for access to return values and exceptions when the source code did not originally provide for such access.